import uvicorn
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
    get_swagger_ui_oauth2_redirect_html,
)

from app.api.routes import setup_routes
from app.core.config import settings
from app.core.logging import logger
from app.schemas.token import APIResponse

logger.info("Starting application with log level: %s", settings.LOG_LEVEL)

def create_app():
    """创建FastAPI应用实例"""
    app = FastAPI(
        title=settings.PROJECT_NAME,
        openapi_url=f"{settings.API_V1_STR}/openapi.json",
        docs_url=None,  # 禁用默认的/docs路由
        redoc_url=None  # 禁用默认的/redoc路由
    )
    
    # 添加请求日志中间件
    @app.middleware("http")
    async def log_requests(request: Request, call_next):
        logger.debug(f"请求路径: {request.url.path}")
        logger.debug(f"请求方法: {request.method}")
        logger.debug(f"请求头: {request.headers}")
        
        # 尝试获取和记录请求体
        try:
            body = await request.body()
            if body:
                logger.debug(f"请求体: {body.decode()}")
        except Exception as e:
            logger.error(f"无法读取请求体: {e}")
        
        # 记录查询参数
        logger.debug(f"查询参数: {request.query_params}")
        
        # 继续处理请求
        response = await call_next(request)
        return response
    
    # 添加自定义异常处理器
    @app.exception_handler(HTTPException)
    async def http_exception_handler(request: Request, exc: HTTPException):
        """自定义HTTP异常处理器，返回统一的APIResponse格式"""
        logger.error(f"HTTP异常: {exc.status_code} - {exc.detail}")
        # 如果detail是APIResponse对象，直接使用
        if isinstance(exc.detail, APIResponse):
            return JSONResponse(
                status_code=exc.status_code,
                content=exc.detail.model_dump()
            )
        
        # 如果detail是字典，包装成APIResponse格式
        if isinstance(exc.detail, dict):
            error_response = APIResponse(
                code=exc.status_code,
                msg=exc.detail.get("msg", "请求错误"),
                data=exc.detail.get("data")
            )
        else:
            # 如果detail是字符串，包装成APIResponse格式
            error_response = APIResponse(
                code=exc.status_code,
                msg=str(exc.detail),
                data=None
            )
        
        return JSONResponse(
            status_code=exc.status_code,
            content=error_response.model_dump()
        )
    
    # 自定义Swagger UI路由
    @app.get("/docs", include_in_schema=False)
    async def custom_swagger_ui_html():
        return get_swagger_ui_html(
            openapi_url=app.openapi_url,
            title=app.title + " - Swagger UI",
            oauth2_redirect_url="/docs/oauth2-redirect",
            init_oauth=None,
        )

    @app.get("/docs/oauth2-redirect", include_in_schema=False)
    async def swagger_ui_redirect():
        return get_swagger_ui_oauth2_redirect_html()
    
    # 自定义ReDoc路由
    @app.get("/redoc", include_in_schema=False)
    async def custom_redoc_html():
        return get_redoc_html(
            openapi_url=app.openapi_url,
            title=app.title + " - ReDoc",
        )

    # 允许跨域 - 允许所有源访问
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],  # 允许所有源访问
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    # 配置路由
    setup_routes(app)
    
    return app

app = create_app()

def main():
    """应用主函数"""
    logger.info("Starting server on 0.0.0.0:8001")
    uvicorn.run(app, host="0.0.0.0", port=8001, log_config=None)  # 使用app.core.logging中配置的日志系统

if __name__ == "__main__":
    main()